home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 619 / mod_env.src next >
Encoding:
C/C++ Source or Header  |  1992-07-28  |  6.8 KB  |  231 lines

  1. Newsgroups: comp.sys.atari.st.tech
  2. Path: news.cis.umn.edu!umn.edu!The-Star.honeywell.com!sol.ctr.columbia.edu!zaphod.mps.ohio-state.edu!wupost!uunet!mnemosyne.cs.du.edu!nyx!ilepore
  3. From: ilepore@nyx.cs.du.edu (Ian Lepore)
  4. Subject: Re: Passing modified environment to child process--HOW?
  5. Message-ID: <1992Jul16.070022.21116@mnemosyne.cs.du.edu>
  6. X-Disclaimer: Nyx is a public access Unix system run by the University    of Denver for the Denver community.  The University has neither    control over nor responsibility for the opinions of users.
  7. Sender: usenet@mnemosyne.cs.du.edu (netnews admin account)
  8. Reply-To: ilepore@nyx.UUCP (Ian Lepore)
  9. Organization: Nyx, Public Access Unix at U. of Denver Math/CS dept.
  10. References: <75723@ut-emx.uucp>
  11. Date: Thu, 16 Jul 92 07:00:22 GMT
  12. Lines: 217
  13.  
  14.  
  15.  
  16.  I got a couple email requests to post the code for passing environ[]
  17. vars via Pexec(), so here it is...  Note that this also passes
  18. args via the Atari ARGV standard.
  19.  
  20. --------- cut here ----------------------------------------------------
  21.  /* SPAWN.C */
  22. #include <stdlib.h>
  23. #include <errno.h>
  24. #include <osbind.h>
  25.  
  26. static char *nullenv[] = {NULL};
  27.  
  28.  /*------------------------------------------------------------------------
  29.   * Return the total length of the characters and null terminators in
  30.   * an array of pointers to strings terminated by a NULL pointer.
  31.   *------------------------------------------------------------------------
  32.  
  33. static unsigned e_strlen(strings)
  34.     register char     **strings;
  35. {
  36.     register char     *pstring;
  37.     register unsigned length = 0;
  38.  
  39.     while (*strings) {
  40.         length += 1 + strlen(*strings++);   /* +1 for nullterm char */
  41.     }
  42.     return length;    
  43. }
  44.  
  45.  /*------------------------------------------------------------------------
  46.   * Copy a string, including the null terminator, and return a pointer
  47.   * to the end of the destination string.
  48.   *------------------------------------------------------------------------
  49.  
  50. static char *str0cpy(dest, source)
  51.     register char *dest;
  52.     register char *source;
  53. {
  54.     while (*dest++ = *source++)
  55.         continue;
  56.     return dest;
  57. }
  58.  
  59.  /*------------------------------------------------------------------------
  60.   * Copy an array of strings into an environment string, and return a point
  61.   * to the end of the environment string.
  62.   *------------------------------------------------------------------------
  63.  
  64. static char *e_strcpy(envstring, strings)
  65.     register char *envstring;
  66.     register char **strings;
  67. {
  68.     while( *strings != 0 ) {
  69.         envstring = str0cpy( envstring, *strings );
  70.         ++strings;
  71.     }
  72.     return envstring;               /* Return end of environment string */
  73. }
  74.  
  75.  /*------------------------------------------------------------------------
  76.   * Run a program, passing it arguments according to the ARGV spec.
  77.   *------------------------------------------------------------------------
  78.  
  79. int _Execve(childname, args, envv)
  80.     char *childname;
  81.     char **args;
  82.     char **envv;
  83. {
  84.         register unsigned   envsize;
  85.         long                rv;
  86.         register char       *penvargs; 
  87.         register char       *ptail;
  88.         char                *childenv; 
  89.         register char       *pchildenv;
  90.         register unsigned   lentail;
  91.         register char       argch,;
  92.         char                tail[128];
  93. static  char    argvar[] = "ARGV=";
  94.  
  95.  /*
  96.   * Find out how much memory we'll need for the child's environment
  97.   */
  98.   
  99.     if (NULL == envv) {                 /* use global environ if specific *
  100.         if (NULL == (envv = environ))   /* environ wasn't given; if global*
  101.             envv = nullenv;             /* env is not valid, use dummy.   *
  102.     }
  103.  
  104.     envsize  = e_strlen(envv);          /* length of environment           
  105.     envsize += e_strlen(args);          /* plus command tail args          
  106.     envsize += 1 + strlen(childname);   /* plus length of argv[0]          
  107.     envsize += 7;                       /* plus length of ARGV= var        
  108.     envsize += envsize & 1;             /* padded to even # of bytes.      
  109.  
  110.  /*
  111.   * Allocate and fill in the child's environment
  112.   */
  113.  
  114.     childenv = (char *)(rv = Malloc(envsize));
  115.     if( rv < 0 ) {
  116.         return rv; /* Malloc error */
  117.     }
  118.     
  119.     pchildenv  = e_strcpy(childenv, envv);      /* copy caller environment 
  120.     pchildenv  = str0cpy(pchildenv, argvar);    /* append ARGV variable    
  121.     pchildenv  = str0cpy(pchildenv, args[0]);   /* copy argv[0]            
  122.     penvargs   = pchildenv;                     /* save start of args      
  123.     pchildenv  = e_strcpy(pchildenv, &args[1]); /* append rest of argv[]   
  124.     *pchildenv = 0;                             /* terminate environment   
  125.  
  126.  /* put as much in the command tail as will fit */
  127.     
  128.     lentail = 0;
  129.     ptail   = &tail[1];
  130.     while(lentail < 125 && penvargs < pchildenv) {
  131.         ++lentail;
  132.         argch = *penvargs++;
  133.         if( argch == 0 ) {
  134.             *ptail++ = ' ';
  135.         } else {
  136.             *ptail++ = argch;
  137.         }
  138.     }
  139.     while (lentail < 126) { /* pad remainder of command tail with nulls */
  140.         ++lentail;
  141.         *ptail++ = '\0';    
  142.     }
  143.     tail[0] = 127;  /* indicate valid ARGV present */
  144.     
  145.  /*
  146.   * Execute child, returning program status or error
  147.   */
  148.  
  149.     rv = Pexec(0, childname, tail, childenv);
  150.     
  151.     Mfree(childenv);
  152.     
  153.     if (rv < 0L) {
  154.         errno = rv;
  155.         return ERROR;
  156.     } else {
  157.         return rv;
  158.     }
  159. }
  160.  
  161.  /*------------------------------------------------------------------------
  162.   * count the number of pointers in an argv[] array.
  163.   *------------------------------------------------------------------------
  164.  
  165. static int count_argv(argv)
  166.     register char **argv;
  167. {
  168.     register int counter = -1;
  169.     
  170.     for (;;) {
  171.         ++counter;
  172.         if (*argv++ == NULL) {
  173.             return counter;
  174.         }
  175.     }
  176. }
  177.  
  178.  /*------------------------------------------------------------------------
  179.   * the spawn-family functions...
  180.   *  (macros in process.h map these things to their proper names)
  181.   *------------------------------------------------------------------------
  182.  
  183. int _Spv(mode, childname, argv)
  184.     int     mode;
  185.     char    *childname;
  186.     char    **argv;
  187. {
  188.     return _Execve(childname, argv, NULL);
  189. }
  190.  
  191. int _Spve(mode, childname, argv, envv)
  192.     int     mode;
  193.     char    *childname;
  194.     char    **argv;
  195.     char    **envv;
  196. {
  197.     return _Execve(childname, argv, envv);
  198. }
  199.  
  200.  
  201. int _Spl(mode, childname, arg0)
  202.     int     mode;
  203.     char    *childname;
  204.     char    *arg0;
  205. {
  206.     return _Spv(mode, childname, &arg0);
  207. }
  208.  
  209. int _Sple(mode, childname, arg0)
  210.     int     mode;
  211.     char    *childname;
  212.     char    *arg0;
  213. {
  214.     register char    **argv;
  215.     register void    *envp;
  216.     register int     argc;
  217.     
  218.     argv = &arg0;
  219.     argc = count_argv(argv);
  220.     envp = &argv[argc+1];
  221.     
  222.     return _Spve(mode, childname, argv, envp);
  223. }
  224. --------------- cut here ------------------------------
  225.  
  226.  
  227. --
  228. - Ian
  229. (void *) where prohibited by law
  230.  
  231.